package utils

import (
	"encoding/hex"
	"fmt"
	"strconv"
)

// 数据前位 0 补足到指定宽度的倍数
func FillWidth(str string, width int) string {
	l := len(str)
	// 前位补足
	if less := l % width; less != 0 {
		str = fmt.Sprintf("%0[1]*s%s", width-less, "", str)
	}
	return str
}

// 十六进制 转换成 二进制
func HexToBinary(hex string) (bin string, err error) {
	length := len(hex)
	// int64 最大可接收 15 个 F, 再大就超出范围了
	for i := 0; i < length; i = i + 15 {
		max := i + 15
		if max > length-1 {
			max = length
		}
		var num int64
		num, err = strconv.ParseInt(hex[i:max], 16, 64)
		if err != nil {
			return
		}
		bin += FillWidth(fmt.Sprintf("%b", num), 4)
	}
	return
}

// 二进制 转换成 十六进制
func BinaryToHex(bin string) (hex string, err error) {
	bin = FillWidth(bin, 4)
	length := len(bin)
	// int64 最大可接收 63 个 1, 再大就超出范围了, 所以这里取最大的 4 的倍数(1倍就是一个十六进制)
	for i := 0; i < length; i = i + 60 {
		max := i + 60
		if max > length-1 {
			max = length
		}
		var num int64
		num, err = strconv.ParseInt(bin[i:max], 2, 64)
		if err != nil {
			return
		}
		hex += fmt.Sprintf("%X", num)
	}
	return
}

// 字符串 转换成 十六进制
func StringToHex(str string) (bin string) {
	return hex.EncodeToString([]byte(str))
}

// 十六进制 转换成 字符串
func HexToString(str string) (string, error) {
	b, err := hex.DecodeString(str)
	if err != nil {
		return "", err
	}
	return string(b), nil
}

// 字符串 转换成 二进制
func StringToBinary(str string) (string, error) {
	return HexToBinary(StringToHex(str))
}

// 二进制 转换成 字符串
func BinaryToString(bin string) (string, error) {
	hex, err := BinaryToHex(bin)
	if err != nil {
		return "", err
	}
	return HexToString(hex)
}
